package cn.lg.soar.flow.biz.service.impl;

import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.current.CurrentProxy;
import cn.lg.soar.flow.api.model.node.ApprovalNode;
import cn.lg.soar.flow.api.utils.ProcessUtils;
import cn.lg.soar.flow.biz.entity.SoarProcess;
import cn.lg.soar.flow.biz.entity.SoarProcessVersion;
import cn.lg.soar.flow.biz.mapper.SoarProcessMapper;
import cn.lg.soar.flow.biz.mapper.SoarProcessVersionMapper;
import cn.lg.soar.flow.biz.service.SoarProcessVersionService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 节点审批人
 * @author luguoxiang
 * @since 2025-08-07
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class SoarProcessVersionServiceImpl extends ServiceImpl<SoarProcessVersionMapper, SoarProcessVersion>
        implements SoarProcessVersionService, CurrentProxy<SoarProcessVersionService> {

    @Autowired
    private SoarProcessMapper soarProcessMapper;

    @Override
    public SoarProcessVersion getByProcInstId(String procInstId) {
        return lambdaQuery()
                .exists("select 1 from act_hi_procinst b where b.PROC_DEF_ID_=lg_flow_process_version.id and b.PROC_INST_ID_={0}", procInstId)
                .one();
    }

    @Cacheable(cacheNames = "flow", key = "#p0")
    @Override
    public SoarProcessVersion getById(Serializable id) {
        return super.getById(id);
    }

    @Cacheable(cacheNames = "flowNode", key = "#p0")
    @Override
    public Map<String, ApprovalNode> getNodeMap(String id) {
        SoarProcessVersion process = proxy().getById(id);
        List<ApprovalNode> approvalNodes = ProcessUtils.getApprovalNodes(process.getNodes());
        return approvalNodes.stream()
                .collect(Collectors.toMap(ApprovalNode::getKey, x -> x));
    }

    @Cacheable(cacheNames = "flowCode", key = "#p0")
    @Override
    public SoarProcessVersion getByCode(String flowCode) {
        SoarProcess soarProcess = soarProcessMapper.selectOne(
                Wrappers.<SoarProcess>lambdaQuery()
                        .select(SoarProcess::getVersionId, SoarProcess::getDisabled)
                        .eq(SoarProcess::getCode, flowCode)
        );
        if (soarProcess == null) {
            throw new RuntimeException("流程定义不存在，key: " + flowCode);
        }
        AssertUtil.isFalse(soarProcess.getDisabled(), "流程已禁用");
        AssertUtil.notEmpty(soarProcess.getVersionId(), "流程未部署");
        return proxy().getById(soarProcess.getVersionId());
    }

}
